﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Pg.BioMedics.SDR.Entities;
using Pg.BioMedics.SDR.Data.Constants;

namespace Pg.BioMedics.SDR.Data
{
    /// <summary>
    /// Entry poit for all data access routines connected 
    /// with Content entity
    /// </summary>
    public class ContentManager : BaseDataManager
    {
        #region Constructors

        /// <summary>
        /// Creates instance of ContentManager and provides
        /// necessary initialization required by data mapper strategy
        /// </summary>
        /// <param name="dataMapperStrategy"></param>
        internal ContentManager(IDataMapperStrategy dataMapperStrategy)
            : base(dataMapperStrategy) { }

        #endregion

        #region Methods

        /// <summary>
        /// Inserts a new content into the database
        /// </summary>
        /// <param name="content">New content</param>
        /// <returns>Saved content</returns>
        public virtual Content InsertContent(Content content)
        {
            try
            {
                DataMapper.Insert(ContentStoredProcedures.InsertContent, content);
                ThrowInsertContentException(content);

                return content;
            }
            catch (Exception ex)
            {
                throw new SDRDataException("Cannot insert content", ex);
            }
        }

        /// <summary>
        /// Gets content by its unique id
        /// </summary>
        /// <param name="contentId">Content unique id</param>
        /// <returns>Content instance or null if not exists</returns>
        public virtual Content GetContentById(int contentId)
        {
            try
            {
                Dictionary<string, object> parameters = new Dictionary<string, object>();
                parameters.Add("ContentId", contentId);

                return DataMapper.QueryForObject<Content>(ContentStoredProcedures.GetContentById, parameters);
            }
            catch (Exception ex)
            {
                throw new SDRDataException("Cannot get content by id {0}", ex, contentId);
            }
        }

        /// <summary>
        /// Sets conent status
        /// </summary>
        /// <param name="content">Saved content</param>
        /// <param name="statusCode">Conent status code</param>
        public virtual void SetContentStatus(Content content, string statusCode)
        {
            try
            {
                Dictionary<string, object> parameters = new Dictionary<string,object>();
                parameters.Add("ContentId", content.Id);
                parameters.Add("StatusCode", statusCode);

                DataMapper.Insert(ContentStoredProcedures.SetContentStatus, parameters);
                ThrowSetContentStatusException((int)parameters["Result"], content, statusCode);
            }
            catch (Exception ex)
            {
                throw new SDRDataException("Cannot set content status", ex);
            }
        }

        #endregion

        #region Support methods

        /// <summary>
        /// Throws appropriate exception for error code returned by InsertContent stored procedure
        /// </summary>
        /// <param name="content"></param>
        private void ThrowInsertContentException(Content content)
        {
            switch (content.Id)
            {
                case -1:
                    throw new SDRDataException("Content type code {0} is invalid", content.TypeCode);
            }
        }

        /// <summary>
        /// Throws appropriate exception for error code returned by SetContentStatus stored 
        /// procedure
        /// </summary>
        /// <param name="result">Error code</param>
        /// <param name="content"></param>
        /// <param name="statusCode"></param>
        private void ThrowSetContentStatusException(int result, Content content, string statusCode)
        {
            switch (result)
            {
                case -1:
                    throw new SDRDataException("Content item {0} doesnot exist", content.Id);
                case -2:
                    throw new SDRDataException("Status code {0} is invalid", statusCode);
            }
        }

        #endregion
    }
}
